package handlers

import (
	"archive/zip"
	"bytes"
	"errors"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"license-manager/internal/api/middleware"
	"license-manager/internal/config"
	"license-manager/internal/models"
	"license-manager/internal/service"
	"license-manager/pkg/i18n"

	"github.com/gin-gonic/gin"
)

type AuthorizationCodeHandler struct {
	authCodeService service.AuthorizationCodeService
}

// NewAuthorizationCodeHandler 创建授权码处理器
func NewAuthorizationCodeHandler(authCodeService service.AuthorizationCodeService) *AuthorizationCodeHandler {
	return &AuthorizationCodeHandler{
		authCodeService: authCodeService,
	}
}

// CreateAuthorizationCode 创建授权码
// @Summary 创建授权码
// @Description 创建新的授权码，自动生成授权码字符串。有效期从当天00:00:00开始，到指定天数后的23:59:59结束
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param authorization_code body models.AuthorizationCodeCreateRequest true "授权码信息"
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCodeCreateResponse} "创建成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "客户不存在"
// @Failure 409 {object} models.ErrorResponse "授权码已存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes [post]
func (h *AuthorizationCodeHandler) CreateAuthorizationCode(c *gin.Context) {
	var req models.AuthorizationCodeCreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message + ": " + err.Error(),
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	data, err := h.authCodeService.CreateAuthorizationCode(c, &req)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    data,
	})
}

// GetAuthorizationCodeList 查询授权码列表
// @Summary 查询授权码列表
// @Description 分页查询授权码列表，支持筛选和排序
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "页码，默认1" minimum(1)
// @Param page_size query int false "每页条数，默认20，最大100" minimum(1) maximum(100)
// @Param customer_id query string false "客户ID筛选"
// @Param status query string false "状态筛选" Enums(normal, locked, expired)
// @Param start_date query string false "创建开始时间"
// @Param end_date query string false "创建结束时间"
// @Param sort query string false "排序字段，默认created_at" Enums(created_at, updated_at, code)
// @Param order query string false "排序方向，默认desc" Enums(asc, desc)
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCodeListResponse} "查询成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes [get]
func (h *AuthorizationCodeHandler) GetAuthorizationCodeList(c *gin.Context) {
	var req models.AuthorizationCodeListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message + ": " + err.Error(),
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	data, err := h.authCodeService.GetAuthorizationCodeList(c, &req)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    data,
	})
}

// GetAuthorizationCode 获取授权码详情
// @Summary 获取授权码详情
// @Description 根据授权码ID获取授权码详细信息
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "查询成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id} [get]
func (h *AuthorizationCodeHandler) GetAuthorizationCode(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	data, err := h.authCodeService.GetAuthorizationCode(c, id)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    data,
	})
}

// DownloadAuthorizationFile 下载授权文件
// @Summary 下载授权文件
// @Description 下载授权码文件，包含授权码和RSA公钥，供客户端使用
// @Tags 授权码管理
// @Accept json
// @Produce application/zip
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Success 200 {file} binary "包含授权码文件和RSA公钥的压缩包"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 409 {object} models.ErrorResponse "授权码不可用"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id}/download [get]
func (h *AuthorizationCodeHandler) DownloadAuthorizationFile(c *gin.Context) {
	lang := middleware.GetLanguage(c)
	id := c.Param("id")
	if id == "" {
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	ctx := middleware.WithLanguage(c.Request.Context(), c)

	fileData, fileName, authCode, err := h.authCodeService.GenerateAuthorizationFile(ctx, id)
	if err != nil {
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	cfg := config.GetConfig()
	if cfg == nil || cfg.License.RSA.PublicKeyPath == "" {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	publicKeyPath := filepath.Clean(cfg.License.RSA.PublicKeyPath)
	publicKeyData, err := os.ReadFile(publicKeyPath)
	if err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	var buffer bytes.Buffer
	zipWriter := zip.NewWriter(&buffer)

	const zipAuthFileName = "authorization_code.txt"
	authFileWriter, err := zipWriter.Create(zipAuthFileName)
	if err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}
	if _, err := authFileWriter.Write(fileData); err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	publicKeyWriter, err := zipWriter.Create("rsa_public_key.pem")
	if err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}
	if _, err := publicKeyWriter.Write(publicKeyData); err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	if err := zipWriter.Close(); err != nil {
		status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	packageFileName := fmt.Sprintf("authorization_package_%s.zip", strings.TrimSpace(authCode))
	if strings.TrimSpace(authCode) == "" {
		baseName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
		packageFileName = fmt.Sprintf("%s_package.zip", baseName)
	}

	c.Header("Content-Description", "File Transfer")
	c.Header("Content-Type", "application/zip")
	c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", packageFileName))
	c.Header("Content-Transfer-Encoding", "binary")
	c.Header("Cache-Control", "must-revalidate")
	c.Header("Pragma", "public")
	c.Data(http.StatusOK, "application/zip", buffer.Bytes())
}

// UpdateAuthorizationCode 更新授权码
// @Summary 更新授权码
// @Description 更新授权码信息，所有字段都是可选的，需要指定变更类型和原因
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Param authorization_code body models.AuthorizationCodeUpdateRequest true "授权码信息"
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "更新成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id} [put]
func (h *AuthorizationCodeHandler) UpdateAuthorizationCode(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	var req models.AuthorizationCodeUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message + ": " + err.Error(),
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	authCode, err := h.authCodeService.UpdateAuthorizationCode(c, id, &req)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    authCode,
	})
}

// LockUnlockAuthorizationCode 锁定/解锁授权码
// @Summary 锁定/解锁授权码
// @Description 锁定或解锁指定的授权码，可以设置锁定原因
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Param lock_request body models.AuthorizationCodeLockRequest true "锁定/解锁信息"
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "操作成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id}/lock [put]
func (h *AuthorizationCodeHandler) LockUnlockAuthorizationCode(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	var req models.AuthorizationCodeLockRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message + ": " + err.Error(),
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	data, err := h.authCodeService.LockUnlockAuthorizationCode(c, id, &req)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    data,
	})
}

// DeleteAuthorizationCode 删除授权码
// @Summary 删除授权码
// @Description 删除指定的授权码（软删除）
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Success 200 {object} models.APIResponse "删除成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id} [delete]
func (h *AuthorizationCodeHandler) DeleteAuthorizationCode(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	if err := h.authCodeService.DeleteAuthorizationCode(c, id); err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    nil,
	})
}

// GetAuthorizationChangeList 查询授权变更历史列表
// @Summary 查询授权变更历史列表
// @Description 分页查询指定授权码的变更历史，支持筛选
// @Tags 授权码管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "授权码ID"
// @Param page query int false "页码，默认1" minimum(1)
// @Param page_size query int false "每页条数，默认20，最大100" minimum(1) maximum(100)
// @Param change_type query string false "变更类型筛选"
// @Param operator_id query string false "操作人筛选"
// @Param start_date query string false "开始时间 (YYYY-MM-DD格式)"
// @Param end_date query string false "结束时间 (YYYY-MM-DD格式)"
// @Param sort query string false "排序字段，默认created_at" Enums(created_at, change_type)
// @Param order query string false "排序方向，默认desc" Enums(asc, desc)
// @Success 200 {object} models.APIResponse{data=models.AuthorizationChangeListResponse} "查询成功"
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
// @Failure 401 {object} models.ErrorResponse "未认证"
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
// @Router /api/v1/authorization-codes/{id}/changes [get]
func (h *AuthorizationCodeHandler) GetAuthorizationChangeList(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message,
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	var req models.AuthorizationChangeListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		lang := middleware.GetLanguage(c)
		status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
		c.JSON(status, models.ErrorResponse{
			Code:      errCode,
			Message:   message + ": " + err.Error(),
			Timestamp: time.Now().Format(time.RFC3339),
		})
		return
	}

	// 直接传递 gin.Context
	data, err := h.authCodeService.GetAuthorizationChangeList(c, id, &req)
	if err != nil {
		// 错误已经在Service层完全包装好了，直接使用
		var i18nErr *i18n.I18nError
		if errors.As(err, &i18nErr) {
			c.JSON(i18nErr.HttpCode, models.ErrorResponse{
				Code:      i18nErr.Code,
				Message:   i18nErr.Message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		} else {
			// 兜底：理论上不应该到这里，因为Service层应该返回I18nError
			lang := middleware.GetLanguage(c)
			status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
			c.JSON(status, models.ErrorResponse{
				Code:      errCode,
				Message:   message,
				Timestamp: time.Now().Format(time.RFC3339),
			})
		}
		return
	}

	lang := middleware.GetLanguage(c)
	successMessage := i18n.GetErrorMessage("000000", lang)
	c.JSON(http.StatusOK, models.APIResponse{
		Code:    "000000",
		Message: successMessage,
		Data:    data,
	})
}
